unit SyncNodeUnit;

interface

uses
  Classes,
  SysUtils,
  ExtCtrls,
  IdTCPClient,
  IdUDPClient,
  TcpFileServer,
  ConstUnit;

type
  TSyncNode = class
  private
    FFileServer: TTcpFileServer;
    FTrackClient: TIdTCPClient;
    FIp, FLocalIp: string;
    FRefresh: TTimer;
    FTracking: Boolean;
    procedure PutTrack;
    procedure OnRefresh(Sender: TObject);
    function GetBindingIps: string;
    function GetClientCount: Integer;
    function GetPort: Integer;
  public
    constructor Create(AIp: string; APort: Integer = TcpFilePort; ALocalIp: string = '');
    destructor Destroy; override;
    procedure Start;
    procedure Stop;

    property BindingIps: string read GetBindingIps;
    property FilePort: Integer read GetPort;
    property ClientCount: Integer read GetClientCount;
  end;

implementation

uses ProtocolUnit, SyncNodeUtil, FunctionUnit;

{ TSyncNode }

constructor TSyncNode.Create(AIp: string; APort: Integer; ALocalIp: string);
begin
  FIp := AIp;
  FLocalIp := ALocalIp;
  FFileServer := TTcpFileServer.Create(APort);
  FTrackClient := TIdTCPClient.Create(nil);
  FRefresh := TTimer.Create(nil);
  FRefresh.OnTimer := OnRefresh;
  FTracking := False;
end;

destructor TSyncNode.Destroy;
begin
  Stop;
  FFileServer.Free;
  FTrackClient.Free;
  inherited;
end;

function TSyncNode.GetBindingIps: string;
begin
  Result := FFileServer.BindingIps;
  if Result = '0.0.0.0' then
    Result := GetIps;
end;

function TSyncNode.GetClientCount: Integer;
begin
  Result := FFileServer.ClientCount;
end;

function TSyncNode.GetPort: Integer;
begin
  Result := FFileServer.Port;
end;

procedure TSyncNode.OnRefresh(Sender: TObject);
begin
  PutTrack;
end;

procedure TSyncNode.PutTrack;
//  procedure SearchTrack;
//  var
//    udp: TIdUdpClient;
//    s, TrackIp: string;
//    p: PChar;
//    sl, sl1: TStrings;
//    Command: Integer;
//  begin
//    udp := TIdUDPClient.Create(nil);
//    try
//      Command := Track_Search;
////      p := AllocMem(1);
////      Move(Command, p^, SizeOf(Track_Search));
//      s := IntToStr(Track_Search);
//      udp.Broadcast(s, TrackUdpPort);
////      FreeMem( p );
//      s := udp.ReceiveString(3000);
//      if s = '' then
//        Exit;
//      sl := TStringList.Create;
//      try
//        ParseLine(s, ':', SL);
//        if SL.Count <> 2 then
//          Exit;
//
//        sl1 := TStringList.Create;
//        try
//          sl1.CommaText := SL[0];
//          if sl1.Count > 1 then
//          begin
//            Randomize;
//            TrackIp := sl1[Random(sl1.Count)];
//          end
//          else
//            TrackIp := SL[0];
//        finally
//          sl1.Free;
//        end;
//
//        FTrackClient.Host := TrackIp;
//        FTrackClient.Port := StrToIntDef(SL[1], TrackPort);
//        FTrackClient.Connect();
//      finally
//        SL.Free;
//      end;
//
//
//    finally
//      udp.Free;
//    end;
//
//  end;
var
  TryCount, Command: Integer;
  SL, SL1: TStrings;
const
  MaxTryCount = 5;
begin
  if FTracking then
    Exit;
  TryCount := 0;
//  while not FTrackClient.Connected do
//  begin
//    if TryCount > MaxTryCount then
//      Exit;
//    SearchTrack;
//    Inc(TryCount)
//  end;
//  FRefresh.Enabled := False;
  if not FTrackClient.Connected then
  begin
    SL := TStringList.Create;
    try
//      FTracking := True;
//      FunctionUnit.ParseLine(GetTrackServer, ':', SL);
//      if SL.Count <> 2 then
//        Exit;

      if FLocalIp <> '' then
        FTrackClient.BoundIP := FLocalIp;
      FTrackClient.Host := FIp; //SL[0];
      FTrackClient.Port := TrackPort;//StrToIntDef(SL[1], TrackPort);
      if not FTrackClient.Connected then
        FTrackClient.Connect();
  //    SL1 := TStringList.Create;
  //    try
  //
  //    finally
  //      SL1.Free;
  //    end;

    finally
      SL.Free;
      FTracking := False;
    end;
  end;

  Command := Track_SyncNodePut;
  FTrackClient.WriteInteger(Command);
  FTrackClient.WriteLn(Format('%d|%d', [FFileServer.Port, FFileServer.ClientCount]));

end;

procedure TSyncNode.Start;
begin
  FFileServer.Start;
end;

procedure TSyncNode.Stop;
begin
  FFileServer.Stop;
end;

end.
